package com.bob.like.job;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bob.like.constant.ThumbConstant;
import com.bob.like.mapper.BlogMapper;
import com.bob.like.model.entity.Blog;
import com.bob.like.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;

@Component
@Slf4j
public class MoreSyncThumb2DBCompensatoryJob {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private BlogMapper blogMapper;

    @Scheduled(cron = "30 51 15 * * *")
    public void run() {
        log.info("开始执行点赞数据补偿任务...");
        Set<String> thumbKeys = scanKeys(RedisKeyUtil.getThumbSum("") + "*");
        Set<String> blogIdSet = new HashSet<>();

        for (String key : thumbKeys) {
            String blogId = key.replace(ThumbConstant.THUMB_SUM_KEY_PREFIX.replace("%s", ""), "");
            blogIdSet.add(blogId);
        }

        if (CollUtil.isEmpty(blogIdSet)) {
            log.info("暂无临时点赞数据需要补偿。");
            return;
        }

        for (String blogId : blogIdSet) {
            syncThumbToDB(blogId);
        }

        log.info("点赞数据补偿任务完成。");
    }

    private void syncThumbToDB(String blogId) {
        String key = RedisKeyUtil.getThumbSum(blogId);
        Object value = redisTemplate.opsForValue().get(key);
        if (value == null) {
            log.warn("Redis key 不存在: {}", key);
            return;
        }

        int thumbSum;
        try {
            thumbSum = Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            log.error("解析点赞数失败，blogId={}, 原始值={}", blogId, value, e);
            return;
        }

        Blog blog = blogMapper.selectById(blogId);
        if (blog == null) {
            log.warn("数据库中未找到博客，blogId={}", blogId);
            return;
        }

        if (blog.getThumbCount() < thumbSum) {
            LambdaUpdateWrapper<Blog> updateWrapper = Wrappers.lambdaUpdate(Blog.class)
                    .eq(Blog::getId, blogId)
                    .lt(Blog::getThumbCount, thumbSum)
                    .set(Blog::getThumbCount, thumbSum);
            int rows = blogMapper.update(null, updateWrapper);
            log.info("补偿更新成功，blogId={}, 原值={}, 新值={}, rows={}", blogId, blog.getThumbCount(), thumbSum, rows);
        } else {
            log.debug("无需更新，blogId={}, DB={}, Redis={}", blogId, blog.getThumbCount(), thumbSum);
        }
    }

    private Set<String> scanKeys(String pattern) {
        Set<String> keys = new HashSet<>();
        Cursor<byte[]> cursor = redisTemplate.getConnectionFactory()
                .getConnection()
                .scan(ScanOptions.scanOptions().match(pattern).count(1000).build());
        cursor.forEachRemaining(k -> keys.add(new String(k)));
        return keys;
    }
}
